This is an R Markdown
Notebook. When you execute code within the notebook, the results appear
beneath the code.
Try executing this chunk by clicking the Run button within
the chunk or by placing your cursor inside it and pressing
Ctrl+Shift+Enter.
library(dplyr)
library(ggplot2)
library(tidyr)
library(car)
library(MASS)
library(repr)
library(pals)
getwd()
[1] "C:/Users/Natalie/git_proj/Is-your-electric-car-overpriced-"
ecars_raw = ecars_raw %>% rename(Price = Price.DE., Acceleration = acceleration..0.100.)
Error in `rename()`:
! Can't rename columns that don't exist.
✖ Column `Price.DE.` doesn't exist.
Backtrace:
1. ecars_raw %>% rename(Price = Price.DE., Acceleration = acceleration..0.100.)
3. dplyr:::rename.data.frame(., Price = Price.DE., Acceleration = acceleration..0.100.)
make = strsplit(ecars_raw$Car_name, split = ' ')
make_ = c()
n = length(make)
for (i in 1:n) {
make_[i] = make[[i]][1]
}
ecars_raw$Make = make_
ecars_raw = ecars_raw %>% relocate(Make, .before = Car_name_link)
ecars_raw = ecars_raw %>% relocate(Battery, .after = Car_name_link)
ecars_raw
make_colors = c('#e6194b', '#f58231', '#ffe119',
'#bcf60c','#3cb44b', '#008080',
'#aaffc3', '#4363d8', '#000075',
'#46f0f0', '#911eb4', '#e6beff',
'#f032e6', '#fabebe')
summary(price_model_full)
Call:
lm(formula = Price ~ Battery + Efficiency + Fast_charge + Range +
Top_speed + Acceleration, data = ecars)
Residuals:
Min 1Q Median 3Q Max
-53557 -11739 -178 8223 84430
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -1.613e+05 2.398e+04 -6.724 8.91e-11 ***
Battery 2.215e+02 3.506e+02 0.632 0.52798
Efficiency 3.052e+02 1.140e+02 2.678 0.00781 **
Fast_charge 1.785e+01 7.819e+00 2.283 0.02315 *
Range 9.066e+00 6.679e+01 0.136 0.89211
Top_speed 7.013e+02 7.086e+01 9.897 < 2e-16 ***
Acceleration 1.762e+03 7.746e+02 2.274 0.02366 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 18530 on 300 degrees of freedom
Multiple R-squared: 0.7167, Adjusted R-squared: 0.711
F-statistic: 126.5 on 6 and 300 DF, p-value: < 2.2e-16
forwardAIC = step(price_model_empty, scope, direction = 'forward', k = 2)
Start: AIC=6415.84
Price ~ 1
Df Sum of Sq RSS AIC
+ Top_speed 1 2.1023e+11 1.5319e+11 6152.6
+ Battery 1 1.7911e+11 1.8431e+11 6209.4
+ Fast_charge 1 1.3923e+11 2.2419e+11 6269.5
+ Range 1 1.2615e+11 2.3728e+11 6287.0
+ Acceleration 1 1.0296e+11 2.6046e+11 6315.6
+ Efficiency 1 1.1067e+10 3.5235e+11 6408.3
<none> 3.6342e+11 6415.8
Step: AIC=6152.62
Price ~ Top_speed
Df Sum of Sq RSS AIC
+ Efficiency 1 4.2802e+10 1.1039e+11 6054.0
+ Battery 1 1.9965e+10 1.3322e+11 6111.8
+ Acceleration 1 1.5065e+10 1.3812e+11 6122.8
<none> 1.5319e+11 6152.6
+ Fast_charge 1 2.2387e+08 1.5297e+11 6154.2
+ Range 1 7.0491e+07 1.5312e+11 6154.5
Step: AIC=6054.03
Price ~ Top_speed + Efficiency
Df Sum of Sq RSS AIC
+ Fast_charge 1 3519695484 1.0687e+11 6046.1
+ Range 1 3506122724 1.0688e+11 6046.1
+ Battery 1 3063673448 1.0732e+11 6047.4
+ Acceleration 1 915987463 1.0947e+11 6053.5
<none> 1.1039e+11 6054.0
Step: AIC=6046.08
Price ~ Top_speed + Efficiency + Fast_charge
Df Sum of Sq RSS AIC
+ Range 1 2137906570 1.0473e+11 6041.9
+ Battery 1 2032210165 1.0484e+11 6042.2
+ Acceleration 1 713779942 1.0615e+11 6046.0
<none> 1.0687e+11 6046.1
Step: AIC=6041.87
Price ~ Top_speed + Efficiency + Fast_charge + Range
Df Sum of Sq RSS AIC
+ Acceleration 1 1639080066 1.0309e+11 6039.0
<none> 1.0473e+11 6041.9
+ Battery 1 1076868 1.0473e+11 6043.9
Step: AIC=6039.03
Price ~ Top_speed + Efficiency + Fast_charge + Range + Acceleration
Df Sum of Sq RSS AIC
<none> 1.0309e+11 6039.0
+ Battery 1 1.37e+08 1.0295e+11 6040.6
summary(price_model)
Call:
lm(formula = Price_lambda ~ Efficiency + Fast_charge + Range +
Top_speed + Acceleration, data = ecars)
Residuals:
Min 1Q Median 3Q Max
-2.951e-04 -4.127e-05 8.710e-06 4.794e-05 1.467e-04
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.413e+00 5.206e-05 27130.409 < 2e-16 ***
Efficiency 3.059e-06 1.332e-07 22.957 < 2e-16 ***
Fast_charge 1.407e-07 2.675e-08 5.259 2.75e-07 ***
Range 5.510e-07 5.805e-08 9.491 < 2e-16 ***
Top_speed 1.601e-06 2.455e-07 6.524 2.89e-10 ***
Acceleration -4.715e-06 2.603e-06 -1.812 0.071 .
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 6.436e-05 on 301 degrees of freedom
Multiple R-squared: 0.853, Adjusted R-squared: 0.8505
F-statistic: 349.3 on 5 and 301 DF, p-value: < 2.2e-16
prediction = predict(price_model, ecars, interval = 'prediction')
confidence = predict(price_model, ecars, interval = 'confidence')
prediction_dollars = ((prediction * lambda) + 1)^(1/lambda)
confidence_dollars = ((confidence * lambda) + 1)^(1/lambda)
predicted_price = data.frame(Name = ecars$Car_name,
Make = ecars$Make,
Price = ecars$Price/1000,
Predicted = (prediction_dollars[,1]/1000),
Predict_lwr = (prediction_dollars[,2]/1000),
Predict_upr = (prediction_dollars[,3]/1000),
Confidence_lwr = (confidence_dollars[,2]/1000),
Confidence_upr = (confidence_dollars[,3]/1000))
predicted_price
ggplot(NULL, aes(Predicted_price, Price)) +
geom_smooth(data = predicted_price, aes(x = Predicted, y = Predicted), col = 'black', linetype = 'dashed') +
geom_smooth(data = predicted_price, aes(x = Predicted, y = Predict_lwr), col = 'red', linetype = 'dashed') +
geom_smooth(data = predicted_price, aes(x = Predicted, y = Predict_upr), col = 'red') +
geom_smooth(data = predicted_price, aes(x = Predicted, y = Confidence_lwr), col = 'blue') +
geom_smooth(data = predicted_price, aes(x = Predicted, y = Confidence_upr), col = 'blue') +
geom_ribbon(aes(ymin = predicted_price$Confidence_lwr, ymax = predicted_price$Confidence_upr), fill = "grey70")+
ylim(25,150) + xlim(25, 140) +
geom_point(data = predicted_price, aes(x = Predicted, y = Price), alpha = .5) +
geom_point(data = most_makes, aes(x = mean_predicted, y = mean_price, col = Make), size = 3) +
scale_color_manual(values = make_colors) +
xlab("Predicted Price in 1000s of Euros") + ylab("Price in 1000s of Euros") +
ggtitle('Price of Electric Vehicles with mean cost per Make')
Error in `geom_ribbon()`:
! Problem while computing aesthetics.
ℹ Error occurred in the 6th layer.
Caused by error:
! object 'Predicted_price' not found
Backtrace:
1. base (local) `<fn>`(x)
2. ggplot2:::print.ggplot(x)
4. ggplot2:::ggplot_build.ggplot(x)
5. ggplot2:::by_layer(...)
12. ggplot2 (local) f(l = layers[[i]], d = data[[i]])
13. l$compute_aesthetics(d, plot)
14. ggplot2 (local) compute_aesthetics(..., self = self)
15. base::lapply(aesthetics, eval_tidy, data = data, env = env)
16. rlang (local) FUN(X[[i]], ...)



testa = ggplot(NULL, aes(Predicted_price, Price)) +
geom_smooth(data = predicted_price, aes(x = Predicted, y = Predicted),
col = 'blue', size = .8, alpha = .5) +
geom_smooth(data = predicted_price, aes(x = Predicted, y = Predict_lwr),
col = 'red', linetype = 'dashed', size = .8, alpha = .8) +
geom_smooth(data = predicted_price, aes(x = Predicted, y = Predict_upr),
col = 'red', linetype = 'dashed',size = .8, alpha = .8) +
geom_smooth(data = predicted_price, aes(x = Predicted, y = Confidence_lwr),
col = 'black', linetype = 'dashed', size = .8, alpha = .8) +
geom_smooth(data = predicted_price, aes(x = Predicted, y = Confidence_upr),
col = 'black', linetype = 'dashed', size = .8, alpha = .8) +
geom_point(data = predicted_price, aes(x = Predicted, y = Price, text = Name), alpha = .5) +
theme(legend.position = "right", legend.text = element_text(size = 8))+
ylim(25, 250) + xlim(25, 250) +
labs(title = "Predicted Price vs. Price for all EV Models",
caption = "Data source: ToothGrowth",
x = "Predicted price (euros in thousands)", y = "German Price (euros in thousands)",
tag = "A")
Warning: Ignoring unknown aesthetics: text
ggplotly(testa, tooltip = c("x", 'y', "text"))
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'`geom_smooth()` using method = 'loess' and formula = 'y ~ x'Warning: Removed 4 rows containing non-finite values (`stat_smooth()`).`geom_smooth()` using method = 'loess' and formula = 'y ~ x'Warning: Removed 8 rows containing non-finite values (`stat_smooth()`).`geom_smooth()` using method = 'loess' and formula = 'y ~ x'Warning: Removed 1 rows containing non-finite values (`stat_smooth()`).`geom_smooth()` using method = 'loess' and formula = 'y ~ x'Warning: Removed 1 rows containing non-finite values (`stat_smooth()`).

unique(ecars_missing_price$Make)
[1] "Rolls-Royce" "Hongqi" "Audi" "Peugeot" "Mercedes" "Opel" "Polestar" "Hyundai"
[9] "Volkswagen" "XPENG" "CUPRA" "Genesis" "Maserati" "Mini" "Seres" "Volvo"
[17] "Ford" "Lexus" "Skoda" "Fiat" "Kia" "Toyota"




Add a new chunk by clicking the Insert Chunk button on the
toolbar or by pressing Ctrl+Alt+I.
When you save the notebook, an HTML file containing the code and
output will be saved alongside it (click the Preview button or
press Ctrl+Shift+K to preview the HTML file).
The preview shows you a rendered HTML copy of the contents of the
editor. Consequently, unlike Knit, Preview does not
run any R code chunks. Instead, the output of the chunk when it was last
run in the editor is displayed.
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLiANCg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoY2FyKQ0KbGlicmFyeShNQVNTKQ0KbGlicmFyeShyZXByKQ0KbGlicmFyeShwYWxzKQ0KYGBgDQpgYGB7cn0NCmdldHdkKCkNCmVjYXJzX3JhdyA9IHJlYWQuY3N2KCdFVl9jYXJzLmNzdicpDQoNCmBgYA0KYGBge3J9DQplY2Fyc19yYXcgPSBlY2Fyc19yYXcgJT4lIHJlbmFtZShQcmljZSA9IFByaWNlLkRFLiwgQWNjZWxlcmF0aW9uID0gYWNjZWxlcmF0aW9uLi4wLjEwMC4pDQpgYGANCg0KYGBge3J9DQptYWtlID0gc3Ryc3BsaXQoZWNhcnNfcmF3JENhcl9uYW1lLCBzcGxpdCA9ICcgJykNCg0KbWFrZV8gPSBjKCkNCm4gPSBsZW5ndGgobWFrZSkNCg0KZm9yIChpIGluIDE6bikgew0KICBtYWtlX1tpXSA9IG1ha2VbW2ldXVsxXQ0KfQ0KDQplY2Fyc19yYXckTWFrZSA9IG1ha2VfDQpgYGANCg0KDQpgYGB7cn0NCmVjYXJzX3JhdyA9IGVjYXJzX3JhdyAlPiUgcmVsb2NhdGUoTWFrZSwgLmJlZm9yZSA9IENhcl9uYW1lX2xpbmspDQplY2Fyc19yYXcgPSBlY2Fyc19yYXcgJT4lIHJlbG9jYXRlKEJhdHRlcnksIC5hZnRlciA9IENhcl9uYW1lX2xpbmspDQplY2Fyc19yYXcNCmBgYA0KDQpgYGB7cn0NCmVjYXJzX3JhdyA9IGVjYXJzX3JhdyAlPiUgZmlsdGVyKCFpcy5uYShGYXN0X2NoYXJnZSkpDQplY2FycyA9IGVjYXJzX3JhdyAlPiUgZmlsdGVyKCFpcy5uYShQcmljZSkpDQplY2Fyc19taXNzaW5nX3ByaWNlID0gZWNhcnNfcmF3ICU+JSBmaWx0ZXIoaXMubmEoUHJpY2UpKQ0Kd3JpdGUuY3N2KGVjYXJzLGZpbGU9Jy9Vc2Vycy9OYXRhbGllL2dpdF9wcm9qL0lzLXlvdXItZWxlY3RyaWMtY2FyLW92ZXJwcmljZWQtL2VjYXJzLmNzdicsIHJvdy5uYW1lcz1GQUxTRSkNCndyaXRlLmNzdihtb3N0X21ha2VzLGZpbGU9Jy9Vc2Vycy9OYXRhbGllL2dpdF9wcm9qL0lzLXlvdXItZWxlY3RyaWMtY2FyLW92ZXJwcmljZWQtL21vc3RfbWFrZXMuY3N2Jywgcm93Lm5hbWVzPUZBTFNFKQ0KDQpgYGANCmBgYHtyfQ0KbWFrZV9jb2xvcnMgPSBjKCcjZTYxOTRiJywgJyNmNTgyMzEnLCAgJyNmZmUxMTknLCANCiAgICAgICAgICAgICAgICAnI2JjZjYwYycsJyMzY2I0NGInLCAnIzAwODA4MCcsDQogICAgICAgICAgICAgICAgJyNhYWZmYzMnLCAnIzQzNjNkOCcsICcjMDAwMDc1JywNCiAgICAgICAgICAgICAgICAnIzQ2ZjBmMCcsICcjOTExZWI0JywgJyNlNmJlZmYnLA0KICAgICAgICAgICAgICAgICcjZjAzMmU2JywgJyNmYWJlYmUnKQ0KYGBgDQoNCmBgYHtyfQ0KcHJpY2VfbW9kZWxfZW1wdHkgPSBsbShQcmljZSB+IDEsIGRhdGEgPSBlY2FycykNCnByaWNlX21vZGVsX2Z1bGw9IGxtKFByaWNlIH4gQmF0dGVyeSArIEVmZmljaWVuY3kgKyBGYXN0X2NoYXJnZSArIFJhbmdlICsgVG9wX3NwZWVkICsgQWNjZWxlcmF0aW9uLCBkYXRhID0gZWNhcnMpDQpzdW1tYXJ5KHByaWNlX21vZGVsX2Z1bGwpDQpgYGANCmBgYHtyfQ0KZWNhcnNfbWlzc2luZ19wcmljZQ0KYGBgDQoNCmBgYHtyfQ0Kc2NvcGUgPSBsaXN0KGxvd2VyID0gZm9ybXVsYShwcmljZV9tb2RlbF9lbXB0eSksIHVwcGVyID0gZm9ybXVsYShwcmljZV9tb2RlbF9mdWxsKSkNCmZvcndhcmRBSUMgPSBzdGVwKHByaWNlX21vZGVsX2VtcHR5LCBzY29wZSwgZGlyZWN0aW9uID0gJ2ZvcndhcmQnLCBrID0gMikNCmBgYA0KDQpgYGB7cn0NCnByaWNlX21vZGVsX2luaXRpYWwgPSBsbShQcmljZSB+IEVmZmljaWVuY3kgKyBGYXN0X2NoYXJnZSArIFJhbmdlICsgVG9wX3NwZWVkICsgQWNjZWxlcmF0aW9uLCBkYXRhID0gZWNhcnMpDQpzdW1tYXJ5KHByaWNlX21vZGVsX2luaXRpYWwpDQpiYyA9IGJveENveChwcmljZV9tb2RlbF9pbml0aWFsKQ0KbGFtYmRhID0gYmMkeFt3aGljaChiYyR5ID09IG1heChiYyR5KSldDQplY2FycyRQcmljZV9sYW1iZGEgPSAoZWNhcnMkUHJpY2VebGFtYmRhIC0gMSkvbGFtYmRhDQpwcmljZV9tb2RlbCA9IGxtKFByaWNlX2xhbWJkYSB+IEVmZmljaWVuY3kgKyBGYXN0X2NoYXJnZSArIFJhbmdlICsgVG9wX3NwZWVkICsgQWNjZWxlcmF0aW9uLCBkYXRhID0gZWNhcnMpDQpzdW1tYXJ5KHByaWNlX21vZGVsKQ0KcGxvdChwcmljZV9tb2RlbCkNCmJyb29tOjpnbGFuY2UocHJpY2VfbW9kZWwpDQpgYGANCg0KYGBge3J9DQpwcmVkaWN0aW9uID0gcHJlZGljdChwcmljZV9tb2RlbCwgZWNhcnMsIGludGVydmFsID0gJ3ByZWRpY3Rpb24nKQ0KY29uZmlkZW5jZSA9IHByZWRpY3QocHJpY2VfbW9kZWwsIGVjYXJzLCBpbnRlcnZhbCA9ICdjb25maWRlbmNlJykNCnByZWRpY3Rpb25fZG9sbGFycyA9ICgocHJlZGljdGlvbiAqIGxhbWJkYSkgKyAxKV4oMS9sYW1iZGEpDQpjb25maWRlbmNlX2RvbGxhcnMgPSAoKGNvbmZpZGVuY2UgKiBsYW1iZGEpICsgMSleKDEvbGFtYmRhKQ0KcHJlZGljdGVkX3ByaWNlID0gZGF0YS5mcmFtZShOYW1lID0gZWNhcnMkQ2FyX25hbWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ha2UgPSBlY2FycyRNYWtlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmljZSA9IGVjYXJzJFByaWNlLzEwMDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByZWRpY3RlZCA9IChwcmVkaWN0aW9uX2RvbGxhcnNbLDFdLzEwMDApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVkaWN0X2x3ciA9IChwcmVkaWN0aW9uX2RvbGxhcnNbLDJdLzEwMDApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVkaWN0X3VwciA9IChwcmVkaWN0aW9uX2RvbGxhcnNbLDNdLzEwMDApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25maWRlbmNlX2x3ciA9IChjb25maWRlbmNlX2RvbGxhcnNbLDJdLzEwMDApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25maWRlbmNlX3VwciA9IChjb25maWRlbmNlX2RvbGxhcnNbLDNdLzEwMDApKQ0KcHJlZGljdGVkX3ByaWNlDQp3cml0ZS5jc3YocHJlZGljdGVkX3ByaWNlLGZpbGU9Jy9Vc2Vycy9OYXRhbGllL2dpdF9wcm9qL0lzLXlvdXItZWxlY3RyaWMtY2FyLW92ZXJwcmljZWQtL3ByZWRpY3RlZF9wcmljZS5jc3YnLCByb3cubmFtZXM9RkFMU0UpDQpgYGANCmBgYHtyfQ0KbW9zdF9tYWtlcyA9IHByZWRpY3RlZF9wcmljZSAlPiUNCiAgZ3JvdXBfYnkoTWFrZSklPiUNCiAgZmlsdGVyKG4oKSA+PSAxMCkgJT4lDQogIHN1bW1hcmlzZShtZWFuX3ByaWNlID0gbWVhbihQcmljZSksIG1lYW5fcHJlZGljdGVkID0gbWVhbihQcmVkaWN0ZWQpKQ0KbW9zdF9tYWtlcw0KYGBgDQpgYGB7cn0NCnByZWRpY3RlZF9wcmljZSAlPiUNCiAgZmlsdGVyKE1ha2UgPT0gJ1BvcnNjaGUnKQ0KYGBgDQoNCg0KYGBge3J9DQoNCmdncGxvdChOVUxMLCBhZXMoUHJlZGljdGVkX3ByaWNlLCBQcmljZSkpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJlZGljdGVkKSwgY29sID0gJ2JsYWNrJykgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0X2x3ciksIGNvbCA9ICdyZWQnKSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IFByZWRpY3RfdXByKSwgY29sID0gJ3JlZCcpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gQ29uZmlkZW5jZV9sd3IpLCBjb2wgPSAnYmx1ZScpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gQ29uZmlkZW5jZV91cHIpLCBjb2wgPSAnYmx1ZScpICsNCiAgICAgIHlsaW0oMCwzMDApICsNCiAgICAgIGdlb21fcG9pbnQoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmljZSksIGFscGhhID0gLjUpICsNCiAgICAgIGdlb21fcG9pbnQoZGF0YSA9IG1vc3RfbWFrZXMsIGFlcyh4ID0gbWVhbl9wcmVkaWN0ZWQsIHkgPSBtZWFuX3ByaWNlLCBjb2wgPSBNYWtlKSwgc2l6ZSA9IDMpICsNCiAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBtYWtlX2NvbG9ycykNCg0KZ2dwbG90KE5VTEwsIGFlcyhQcmVkaWN0ZWRfcHJpY2UsIFByaWNlKSkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0ZWQpLCBjb2wgPSAnYmxhY2snLCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IFByZWRpY3RfbHdyKSwgY29sID0gJ3JlZCcsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJlZGljdF91cHIpLCBjb2wgPSAncmVkJykgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBDb25maWRlbmNlX2x3ciksIGNvbCA9ICdibHVlJykgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBDb25maWRlbmNlX3VwciksIGNvbCA9ICdibHVlJykgKw0KICAgICAgeWxpbSgyNSwxNTApICsgeGxpbSgyNSwgMTQwKSArDQogICAgICBnZW9tX3BvaW50KGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJpY2UpLCBhbHBoYSA9IC41KSArIA0KICAgICAgZ2VvbV9wb2ludChkYXRhID0gbW9zdF9tYWtlcywgYWVzKHggPSBtZWFuX3ByZWRpY3RlZCwgeSA9IG1lYW5fcHJpY2UsIGNvbCA9IE1ha2UpLCBzaXplID0gMykgKw0KICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IG1ha2VfY29sb3JzKSArDQogICAgICB4bGFiKCJQcmVkaWN0ZWQgUHJpY2UgaW4gMTAwMHMgb2YgRXVyb3MiKSArIHlsYWIoIlByaWNlIGluIDEwMDBzIG9mIEV1cm9zIikgKw0KICAgICAgZ2d0aXRsZSgnUHJpY2Ugb2YgRWxlY3RyaWMgVmVoaWNsZXMgd2l0aCBtZWFuIGNvc3QgcGVyIE1ha2UnKQ0KDQoNCiMgZ2VvbV9wb2ludChkYXRhID0gbW9zdF9tYWtlcywgYWVzKHggPSBtZWFuX3ByaWNlLCB5ID0gbWVhbl9wcmVkaWN0ZWQpLCBzaXplID0gMywgc2hhcGUgPSAyMywgZmlsbCA9IG1ha2VfY29sb3JzKSArDQoNCg0KYGBgDQpgYGB7cn0NCiAgIA0KICAgIGdncGxvdChOVUxMLCBhZXMoUHJlZGljdGVkX3ByaWNlLCBQcmljZSkpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJlZGljdGVkKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAnYmx1ZScsIHNpemUgPSAuNSwgYWxwaGEgPSAuOCkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0X2x3ciksIA0KICAgICAgICAgICAgICAgICAgY29sID0gJ3JlZCcsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIGFscGhhID0gLjgpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJlZGljdF91cHIpLCANCiAgICAgICAgICAgICAgICAgIGNvbCA9ICdyZWQnLCBsaW5ldHlwZSA9ICdkYXNoZWQnLCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IENvbmZpZGVuY2VfbHdyKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAnYmxhY2snLCBsaW5ldHlwZSA9ICdkYXNoZWQnLCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IENvbmZpZGVuY2VfdXByKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAnYmxhY2snLCBsaW5ldHlwZSA9ICdkYXNoZWQnLCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3BvaW50KGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJpY2UpLCBhbHBoYSA9IC41KSArDQogICAgICBnZW9tX3BvaW50KGRhdGEgPSBtb3N0X21ha2VzLCBhZXMoeCA9IG1lYW5fcHJlZGljdGVkLCB5ID0gbWVhbl9wcmljZSksIHNpemUgPSAzKSArDQogICAgICBnZW9tX3BvaW50KGRhdGEgPSBtb3N0X21ha2VzLCBhZXMoeCA9IG1lYW5fcHJlZGljdGVkLCB5ID0gbWVhbl9wcmljZSwgY29sID0gTWFrZSksIHNpemUgPSAyKSArDQogICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKSsNCiAgICAgIHlsaW0oMjUsIDI1MCkgKyB4bGltKDI1LCAyNTApICsNCiAgICAgIHhsYWIoIlByZWRpY3RlZCBwcmljZSAoZXVyb3MgaW4gdGhvdXNhbmRzKSIpICsgeWxhYigiUHJpY2UgKGV1cm9zIGluIHRob3VzYW5kcykiKSArDQogICAgICBnZ3RpdGxlKCdQcmVkaWN0ZWQgUHJpY2UgdnMuIFByaWNlIGZvciBhbGwgRVYgTW9kZWxzJykgIA0KYGBgDQoNCmBgYHtyfQ0KIGdncGxvdChOVUxMLCBhZXMoUHJlZGljdGVkX3ByaWNlLCBQcmljZSkpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJlZGljdGVkKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAnYmx1ZScsIHNpemUgPSAuOCwgYWxwaGEgPSAuNSkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0X2x3ciksIA0KICAgICAgICAgICAgICAgICAgY29sID0gJ3JlZCcsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIHNpemUgPSAuOCwgYWxwaGEgPSAuOCkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0X3VwciksIA0KICAgICAgICAgICAgICAgICAgY29sID0gJ3JlZCcsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsc2l6ZSA9IC44LCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IENvbmZpZGVuY2VfbHdyKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAnYmxhY2snLCBsaW5ldHlwZSA9ICdkYXNoZWQnLCBzaXplID0gLjgsIGFscGhhID0gLjgpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gQ29uZmlkZW5jZV91cHIpLCANCiAgICAgICAgICAgICAgICAgIGNvbCA9ICdibGFjaycsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIHNpemUgPSAuOCwgYWxwaGEgPSAuOCkgKw0KICAgICAgZ2VvbV9wb2ludChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IFByaWNlKSwgYWxwaGEgPSAuNSkgKw0KICAgICAgZ2VvbV9wb2ludChkYXRhID0gbW9zdF9tYWtlcywgYWVzKHggPSBtZWFuX3ByZWRpY3RlZCwgeSA9IG1lYW5fcHJpY2UpLCBzaXplID0gMykgKw0KICAgICAgZ2VvbV9wb2ludChkYXRhID0gbW9zdF9tYWtlcywgYWVzKHggPSBtZWFuX3ByZWRpY3RlZCwgeSA9IG1lYW5fcHJpY2UsIGNvbCA9IE1ha2UpLCBzaXplID0gMikgKw0KICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IG1ha2VfY29sb3JzKSArDQogICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpKw0KICAgICAgeWxpbSgyNSwgMTQwKSArIHhsaW0oMjUsIDExMCkgKw0KICAgICAgbGFicyh0aXRsZSA9ICJQcmVkaWN0ZWQgUHJpY2UgdnMuIFByaWNlIGZvciBhbGwgRVYgTW9kZWxzIiwNCiAgICAgICAgICAgc3VidGl0bGUgPSAiTWVhbiBtb2RlbCBwcmljZSBmb3IgbWFrZXMgd2l0aCAxMCsgbW9kZWxzIGluY2x1ZGVkIiwNCiAgICAgICAgICAgY2FwdGlvbiA9ICJEYXRhIHNvdXJjZTogVG9vdGhHcm93dGgiLA0KICAgICAgICAgICB4ID0gIlByZWRpY3RlZCBwcmljZSAoZXVyb3MgaW4gdGhvdXNhbmRzKSIsIHkgPSAiR2VybWFuIFByaWNlIChldXJvcyBpbiB0aG91c2FuZHMpIiwNCiAgICAgICAgICAgdGFnID0gIkEiKQ0KYGBgDQoNCmBgYHtyfQ0KDQoNCnRlc3RhID0gZ2dwbG90KE5VTEwsIGFlcyhQcmVkaWN0ZWRfcHJpY2UsIFByaWNlKSkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0ZWQpLCANCiAgICAgICAgICAgICAgICAgIGNvbCA9ICdibHVlJywgc2l6ZSA9IC44LCBhbHBoYSA9IC41KSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IFByZWRpY3RfbHdyKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAncmVkJywgbGluZXR5cGUgPSAnZGFzaGVkJywgc2l6ZSA9IC44LCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IFByZWRpY3RfdXByKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAncmVkJywgbGluZXR5cGUgPSAnZGFzaGVkJyxzaXplID0gLjgsIGFscGhhID0gLjgpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gQ29uZmlkZW5jZV9sd3IpLCANCiAgICAgICAgICAgICAgICAgIGNvbCA9ICdibGFjaycsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIHNpemUgPSAuOCwgYWxwaGEgPSAuOCkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBDb25maWRlbmNlX3VwciksIA0KICAgICAgICAgICAgICAgICAgY29sID0gJ2JsYWNrJywgbGluZXR5cGUgPSAnZGFzaGVkJywgc2l6ZSA9IC44LCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3BvaW50KGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJpY2UsIHRleHQgPSBOYW1lKSwgYWxwaGEgPSAuNSkgKw0KICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKSsNCiAgICAgIHlsaW0oMjUsIDI1MCkgKyB4bGltKDI1LCAyNTApICsNCiAgICAgIGxhYnModGl0bGUgPSAiUHJlZGljdGVkIFByaWNlIHZzLiBQcmljZSBmb3IgYWxsIEVWIE1vZGVscyIsDQogICAgICAgICAgIGNhcHRpb24gPSAiRGF0YSBzb3VyY2U6IFRvb3RoR3Jvd3RoIiwNCiAgICAgICAgICAgeCA9ICJQcmVkaWN0ZWQgcHJpY2UgKGV1cm9zIGluIHRob3VzYW5kcykiLCB5ID0gIkdlcm1hbiBQcmljZSAoZXVyb3MgaW4gdGhvdXNhbmRzKSIsDQogICAgICAgICAgIHRhZyA9ICJBIikNCg0KZ2dwbG90bHkodGVzdGEsIHRvb2x0aXAgPSBjKCJ4IiwgJ3knLCAidGV4dCIpKSANCmBgYA0KDQpgYGB7cn0NCmVjYXJzDQpnZ3Bsb3QoZGF0YSA9IGVjYXJzLCBhZXMoeCA9IEJhdHRlcnksIHkgPSBQcmljZSkpICsgDQogIGdlb21fcG9pbnQoKQ0KYGBgDQoNCmBgYHtyfQ0KdW5pcXVlKGVjYXJzX21pc3NpbmdfcHJpY2UkTWFrZSkNCg0KYGBgDQoNCmBgYHtyfQ0KcHJlZGljdGlvbl9taXNzaW5nID0gcHJlZGljdChwcmljZV9tb2RlbCwgZWNhcnNfbWlzc2luZ19wcmljZSwgaW50ZXJ2YWwgPSAncHJlZGljdGlvbicpDQpwcmVkaWN0aW9uX21pc3NpbmcNCnByZWRpY3Rpb25fbWlzc2luZ19kb2xsYXJzID0gKChwcmVkaWN0aW9uX21pc3NpbmcgKiBsYW1iZGEpICsgMSleKDEvbGFtYmRhKQ0KDQpwcmVkaWN0ZWRfbWlzc2luZ19wcmljZSA9IGRhdGEuZnJhbWUoTmFtZSA9IGVjYXJzX21pc3NpbmdfcHJpY2UkQ2FyX25hbWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ha2UgPSBlY2Fyc19taXNzaW5nX3ByaWNlJE1ha2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByZWRpY3RlZCA9IChwcmVkaWN0aW9uX21pc3NpbmdfZG9sbGFyc1ssMV0vMTAwMCkpDQogICAgICAgICAgICAgICAgICAgICAgICAgICANCnByZWRpY3RlZF9taXNzaW5nX3ByaWNlDQpgYGANCg0KYGBge3J9DQpwcmVkaWN0ZWRfbWlzc2luZ19wcmljZSAlPiUNCiAgZ3JvdXBfYnkoTWFrZSkgJT4lDQogIGZpbHRlcihuKCk+PTMpDQoNCnByZWRpY3RlZF9taXNzaW5nX3ByaWNlICU+JQ0KICBmaWx0ZXIoTWFrZSA9PSAnUm9sbHMtUm95Y2UnKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtbWFyeShwcmljZV9tb2RlbCkNCnBsb3QocHJpY2VfbW9kZWwpDQpzYXZlUkRTKHByaWNlX21vZGVsLCAibW9kZWwucmRzIikNCmBgYA0KDQpgYGB7cn0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQpgYGANCg0KYGBge3J9DQoNCmBgYA0KDQpgYGB7cn0NCg0KYGBgDQoNCmBgYHtyfQ0KDQpgYGANCg0KYGBge3J9DQoNCmBgYA0KDQpgYGB7cn0NCg0KYGBgDQoNCmBgYHtyfQ0KDQpgYGANCg0KYGBge3J9DQoNCmBgYA0KDQpBZGQgYSBuZXcgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpJbnNlcnQgQ2h1bmsqIGJ1dHRvbiBvbiB0aGUgdG9vbGJhciBvciBieSBwcmVzc2luZyAqQ3RybCtBbHQrSSouDQoNCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ3RybCtTaGlmdCtLKiB0byBwcmV2aWV3IHRoZSBIVE1MIGZpbGUpLg0KDQpUaGUgcHJldmlldyBzaG93cyB5b3UgYSByZW5kZXJlZCBIVE1MIGNvcHkgb2YgdGhlIGNvbnRlbnRzIG9mIHRoZSBlZGl0b3IuIENvbnNlcXVlbnRseSwgdW5saWtlICpLbml0KiwgKlByZXZpZXcqIGRvZXMgbm90IHJ1biBhbnkgUiBjb2RlIGNodW5rcy4gSW5zdGVhZCwgdGhlIG91dHB1dCBvZiB0aGUgY2h1bmsgd2hlbiBpdCB3YXMgbGFzdCBydW4gaW4gdGhlIGVkaXRvciBpcyBkaXNwbGF5ZWQuDQo=